字符串问题——替换字符串中连续出现的指定字符串

题目:给定三个字符串str、from和to,把str中的所有from子串替换成to字符串,对连续出现的from子串部分要求只替换成一个to字符串,返回最终的结果字符串。
例:
str=”123abc”, from=”abc”, to=”4567”,返回”1234567”
str=”123abcabc”, from=”abc”, to=”X”,返回”123X”

实现:
1.定义整型变量match,表示匹配到from字符串的什么位置,初始化为match=0
2.遍历str字符串。
1)当str[i]==from[match],如果match==chaf.length,表示str中存在from子串,将str中的这段子串清零;如果match!=chaf.length,只是match++。
2)当str[i]!=from[match],匹配失败,match重置为0。回到from开头重新开始匹配。继续遍历str的下一个字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Replace {
/**
* 方法一:
* 1. 找到str中的所有子串
* 2. 将这些地方置0
* 3. 找到这些连续的0,用to子串替换
* 缺点:若原子串中就有连续零呢?
* @param str
* @param from
* @param to
* @return
*/
public String replace(String str, String from, String to) {
if (str == null || from == null | str.equals("") || from.equals("")) {
return str;
}
char[] chas = str.toCharArray();
char[] chaf = from.toCharArray();
int match = 0;
// 1. 先删除str中的匹配项
for (int i = 0; i < chas.length; i++) {
if (chas[i] == chaf[match++]) {
if (match == chaf.length) {
clear(chas, i, chaf.length);
match = 0;
}
} else { // chas[i] == chaf[j]
match = 0;
}
}
System.out.println(Arrays.toString(chas));
String rst = ""; // rst用来保存0之前的所有字符
String cur = ""; // cur用来保存不为0的字符
for (int i = 0; i < chas.length; i++) {
if (chas[i] != 0) {
cur = cur + String.valueOf(chas[i]);
}
if (chas[i] == 0 && (chas[i - 1] != 0 || i == 0)) {
rst = rst + cur + to;
cur = "";
}
}
if (!cur.equals("")) { // 原字符串匹配子串后面的字符
rst = rst + cur;
}
return rst;
}
/*
* 对匹配到的子串赋0
*/
public void clear(char[] chas, int i, int len) {
while (len-- != 0) {
chas[i--] = 0;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* 方法二:先将str中的from替换成to,然后将to后面的字符串连接
* @param str 原串
* @param from 需要替换的串
* @param to 替换的目标串
* @return 替换后的串
*/
public String replace2(String str, String from, String to) {
Pattern pattern = Pattern.compile(from);
Matcher matcher = pattern.matcher(str);
StringBuffer sb = new StringBuffer();
boolean result = matcher.find();
if (result) {
matcher.appendReplacement(sb, to); //将from找出用to替换,并加到sb中
//result = matcher.find();
}
while (matcher.find()) {
matcher.appendReplacement(sb, "");
}
matcher.appendTail(sb); //将最后一次配后的剩余加到sb中
System.out.println(sb.toString());
return sb.toString();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
	// Test
public static void main(String[] args) {
Replace rp = new Replace();
System.out.println(rp.replace("123abcabc12", "abc", "X"));
rp.replace2("123abcabc12", "abc", "X");
}
}
```
输出:
```
[1, 2, 3, , , , , , ]
123X12
123X12
```

注意下面替换方式的不同

- 替换一次子串:

if (result) {
matcher.appendReplacement(sb, to); //将from找出用to替换,并加到sb中
//result = matcher.find();
}
matcher.appendTail(sb); //将最后一次配后的剩余加到sb中
输出:
123Xabc12

1
2

- 替换多次子串:

while (result) {
matcher.appendReplacement(sb, to);
result = matcher.find();
}
matcher.appendTail(sb);
输出:
123XX12

1
2

- 将多次匹配的子串替换成一个子串:

if (result) {
matcher.appendReplacement(sb, to); //将from找出用to替换,并加到sb中
//result = matcher.find();
}
while (matcher.find()) {
matcher.appendReplacement(sb, “”);
}
matcher.appendTail(sb); //将最后一次配后的剩余加到sb中
输出:
123X12